package com.longway.common.ext.directive;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jfinal.plugin.ehcache.CacheKit;
import com.jfinal.plugin.ehcache.IDataLoader;
import com.jfinal.template.Directive;
import com.jfinal.template.Env;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.ParseException;
import com.jfinal.template.stat.Scope;
import com.longway.common.constant.Const;
import com.longway.common.vo.TreeNode;
import com.longway.core.toolbox.Func;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DropDownDirective extends Directive {
	
	
	@Override
    public void exec(Env env, Scope scope, Writer writer) {
		List<TreeNode> nodeList = new ArrayList<TreeNode>();
		//type="dict" code="101" name="sex" value="0"  tail required  source where
		String[] param = getParaArray(scope);
		String type = param[0];
		String codes = param[1];
		String name = param[2];
		Object value = param[3]==null?"":param[3];
		String tail = "";
		if(param.length>=5){
			tail = param[4]==null?"":param[4];
		}
		String required = "";
		if(param.length>=6){
			required = param[5]==null?"":param[5];
		}
		String source = "";
		if(param.length>=7){
			source = param[6]==null?"":param[6];
		}
		String where = "";
		if(param.length>=8){
			 where = param[7]==null?"":param[7];
		}
		String token = (value.toString().equals("")) ? "token_" : "";
		int lev = 99;
		String code = "";
		String sql = "";
		if(type.equals("dict")) {
		    code = codes.split("_")[0];
		    lev = (codes.split("_").length > 1) ? Func.toInt(codes.split("_")[1]) : 99;
			sql = "select id,(case when pid is null then 0 else pid end) pid,num,name as text from  base_dict where code=" + code + " and num>0";
		}else if (type.equals("user")) {
			sql = "select id,id num,0 as pid,name as text from  base_user";
		}else if (type.equals("dept")) {
			sql = "select id,(case when pid is null then 0 else pid end) pid,num,simplename as text from  base_dept where num>0";
		}else if (type.equals("role")) {
			sql = "select id,(case when pid is null then 0 else pid end) pid,num,name as text from  base_role";
		}else if (type.equals("diy")) {
			type = type + "_" + source;
			Map<String, String> modelOrMap = new HashMap<String, String>();;
			if(StrKit.notBlank(where)){
				where = " where " + where;
			}else{
				where = "";
			}
			SqlPara sqlPara = Db.getSqlPara(source ,modelOrMap);
			sql = sqlPara.getSql() + where;
		}

		final String sqlstr = sql;
		
		List<Record> dict = CacheKit.get(Const.DICT_CACHE,"dropdown_"+ type + "_" + code, new IDataLoader() {
			@Override
			public List<Record> load() {
				return Db.find(sqlstr);
			}
		});

		for (Record d : dict) {
			TreeNode node = new TreeNode();
			node.setId(d.getStr("id"));
			node.setParentId(d.getStr("pid"));
			node.setNum(d.getStr("num"));
			node.setName(d.getStr("text"));
			node.setIsParent(false);
			node.setHasParent(false);
			nodeList.add(node);
		}
		
	    new TreeNode().buildNodes(nodeList);
		
		String sid = "_" + name.split("\\.")[1];

		try {
			writer.write(getDropDownHtml(nodeList, sid, name, value, lev, token, required,tail));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	private String getDropDownHtml(List<TreeNode> nodeList, String id, String name, Object value, int lev, String token, String required,String tail){
		StringBuilder sb = new StringBuilder();
		sb.append("<div class=\"dropdown\">");
		sb.append(" <input type=\"hidden\" id=\"" + id + "\" " + required + " name=\"" + token + name + "\" value=\"" + value + "\" data-target='_DROPDOWN"+id+"' />");
		sb.append(" <input type=\"hidden\" id=\"" + id + "_ext\"  name=\"" + name.split("\\.")[0]+"."+ tail+ "\" value=\"" + value + "\"/>");
		sb.append(" <button data-toggle=\"dropdown\" class=\"btn btn-sx btn-white dropdown-toggle\">");
		sb.append("	 <span id=\"_DROPDOWN" + id + "\">" + findNameByNum(nodeList, value) + "</span> ");
		sb.append("  <i class=\"fa fa-angle-down\"></i>");
		sb.append(" </button>");
		sb.append(" <ul class=\"dropdown-menu multi-level\">");
		sb.append("  <li><a href=\"#\" tabindex=\"-1\" onclick=\"$('#_DROPDOWN" + id + "').html('请选择');$('#" + id + "').val('');$('#form_token').val(1);$('#" + id + "').attr('name','"+name+"');\">清空</a></li>");
		sb.append("  <li class=\"divider\" style=\"margin-top:1px;\"></li>");
		for (TreeNode treeNode : nodeList) {
			sb.append(reloadMenu(treeNode, 0, id, name, lev));
		}
		sb.append(" </ul>");
		sb.append("</div>");
		return sb.toString();
	}
	
	private String reloadMenu(TreeNode treeNode, int levels, String id, String name, int lev){
		StringBuilder sm = new StringBuilder();		
		int parentSize = (Func.isEmpty(treeNode.getParent())) ? 0 : treeNode.getParent().size();
		if(treeNode.isParent() && parentSize == levels && lev > levels + 1){
			List<TreeNode> linkedList = treeNode.getChildren();	
			sm.append("<li class=\"dropdown-submenu\">");
			sm.append(" <a href=\"#\" tabindex=\"-1\" >");
			sm.append(treeNode.getName());
			sm.append(" </a>");
			sm.append(" <ul class=\"dropdown-menu\">");
			for (TreeNode subNode : linkedList) { 
				sm.append(reloadMenu(subNode, levels + 1, id, name, lev));
			}
			sm.append(" </ul>");
			sm.append("</li>");
		} else if(treeNode.isParent() && parentSize == levels && lev == levels + 1){
			sm.append("<li><a href=\"#\" tabindex=\"-1\" onclick=\"$('#_DROPDOWN" + id + "').html('" + treeNode.getName() + "');$('#" + id + "').val('" + treeNode.getId() + "');$('#" + id + "_ext').val('" + treeNode.getName() + "');$('#form_token').val(1);$('#" + id + "').attr('name','"+name+"');\">" + treeNode.getName() + "</a></li>");
		} else if(parentSize > 0){
			if(parentSize == levels && lev >= levels + 1){
				sm.append("<li><a href=\"#\" tabindex=\"-1\" onclick=\"$('#_DROPDOWN" + id + "').html('" + treeNode.getName() + "');$('#" + id + "').val('" + treeNode.getId() + "');$('#" + id + "_ext').val('" + treeNode.getName() + "');$('#form_token').val(1);$('#" + id + "').attr('name','"+name+"');\">" + treeNode.getName() + "</a></li>");
			}
		} else {
			sm.append("<li><a href=\"#\" tabindex=\"-1\" onclick=\"$('#_DROPDOWN" + id + "').html('" + treeNode.getName() + "');$('#" + id + "').val('" + treeNode.getId() + "');$('#" + id + "_ext').val('" + treeNode.getName() + "');$('#form_token').val(1);$('#" + id + "').attr('name','"+name+"');\">" + treeNode.getName() + "</a></li>");
		}
		return sm.toString();
	}
	
	private String findNameByNum(List<TreeNode> nodeList, Object value){
		for (TreeNode treeNode : nodeList) {
			if(treeNode.getId().equals(value.toString())){
				return treeNode.getName();
			}
		}
		return "请选择";
	}
	
	/**
	 * 从 #dropDown 指令参数中获取type="dict" code="101" name="sex" value="0" tail intercepter
	 */
	private String[] getParaArray(Scope scope) {
		Object[] values = exprList.evalExprList(scope);
		String[] ret = new String[values.length];
		if (ret.length == 0) {
			throw new ParseException("#dropDown directive parameter cant not be null", location);
		}
		for (int i=0; i<values.length; i++) {
			if (values[i] instanceof String) {
				ret[i] = (String)values[i];
			}else{
				ret[i] = String.valueOf(values[i]);
			}
		}
		return ret;
	}
	

}